﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Imgur.Net.JSON;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

namespace Imgur.Net
{
    /// <summary>
    /// Transfer object that represents the Imgur image info structure.
    /// </summary>
    [JsonObject(MemberSerialization = MemberSerialization.OptIn)]
    public class ImageInfo
    {
        /// <summary>
        /// Used for automatic serialization and deserialization only.
        /// </summary>
        [JsonConstructor]
        protected ImageInfo()
        {
            
        }

        /// <summary>
        /// Constructs an instance of this object. Fields which are members of this class but are not passed in via parameters will be left to their default
        /// values. Typicalls this will be one of null, long.MinValue, or null depending on data type.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="title"></param>
        /// <param name="description"></param>
        /// <param name="timestamp"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        public ImageInfo(string id, string title, string description, DateTime timestamp, int width, int height) :
            this(id, title, description, timestamp, string.Empty, width, height, long.MinValue, long.MinValue, long.MinValue, null)
        {
            
        }

        /// <summary>
        /// Constructs an instance of this object. Fields which are members of this class but are not passed in via parameters will be left to their default
        /// values. Typicalls this will be one of null, long.MinValue, or null depending on data type.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="title"></param>
        /// <param name="description"></param>
        /// <param name="timestamp"></param>
        /// <param name="mimeType"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="filesize"></param>
        /// <param name="views"></param>
        /// <param name="bandwidth"></param>
        /// <param name="deletehash"></param>
        public ImageInfo(string id, string title, string description, DateTime timestamp, string mimeType, int width, int height, long filesize, long views, long bandwidth, string deletehash )
            : this( id, title, description, timestamp, mimeType, false, width, height, filesize, views, bandwidth, deletehash, string.Empty, string.Empty, false, false, string.Empty )
        {
        }

        /// <summary>
        /// Constructs an instance of this object.
        /// </summary>
        /// <param name="id"></param>
        /// <param name="title"></param>
        /// <param name="description"></param>
        /// <param name="timestamp"></param>
        /// <param name="mimeType"></param>
        /// <param name="isAnumated"></param>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="filesize"></param>
        /// <param name="views"></param>
        /// <param name="bandwidth"></param>
        /// <param name="deletehash"></param>
        /// <param name="section"></param>
        /// <param name="link"></param>
        /// <param name="isFavorite"></param>
        /// <param name="isNsfw"></param>
        /// <param name="accountUrl"></param>
        public ImageInfo(string id, string title, string description, DateTime timestamp, string mimeType, bool isAnimated, int width, int height, long filesize, long views, long bandwidth,
            string deletehash, string section, string link, bool isFavorite, bool isNsfw, string accountUrl )
        {
            this.Id = id;
            this.Title = title;
            this.Description = description;
            this.TimeStamp = timestamp;
            this.MimeType = mimeType;
            this.IsAnimated = isAnimated;
            this.Width = width;
            this.Height = height;
            this.FileSize = filesize;
            this.Views = views;
            this.Bandwidth = bandwidth;
            this.DeleteHash = deletehash;
            this.Section = section;
            this.Link = link;
            this.IsFavorite = isFavorite;
            this.IsNSFW = isNsfw;
            this.AccountUrl = accountUrl;
        }

        /// <summary>
        /// The id of the image. 
        /// </summary>
        /// <remarks>Represented by the "<b>id</b>" JSON value</remarks>
        [JsonProperty]
        public string Id { get; private set; }

        /// <summary>
        /// The title of the image as given by the uploader, if any.
        /// </summary>
        /// <remarks>Represented by the "<b>title</b>" JSON value</remarks>
        [JsonProperty("title")]
        public string Title { get; private set; }

        /// <summary>
        /// The description of the image as given by the uploader, if any.
        /// </summary>
        /// <remarks>Represented by the "<b>description</b>" JSON value</remarks>
        [JsonProperty("description")]
        public string Description { get; private set; }

        /// <summary>
        /// The timestamp of the image upload.
        /// </summary>
        /// <remarks>Represented by the "<b>datetime</b>" JSON value</remarks>
        [JsonProperty("datetime")]
        [JsonConverter(typeof(EpochDateTimeConverter))]
        public DateTime TimeStamp { get; private set; }

        /// <summary>
        /// The MIME type of the image.
        /// </summary>
        /// <remarks>Represented by the "<b>type</b>" JSON value</remarks>
        [JsonProperty("type")]
        public string MimeType { get; private set; }

        /// <summary>
        /// Flag denoting that this image is animated.
        /// </summary>
        /// <remarks>Represented by the "<b>animated</b>" JSON value</remarks>
        [JsonProperty("animated", NullValueHandling = NullValueHandling.Ignore)]
        public bool? IsAnimated { get; private set; }

        /// <summary>
        /// The pixel width of the image.
        /// </summary>
        /// <remarks>Represented by the "<b>width</b>" JSON value</remarks>
        [JsonProperty]
        public int Width { get; private set; }

        /// <summary>
        /// The pixel height of the image.
        /// </summary>
        /// <remarks>Represented by the "<b>height</b>" JSON value</remarks>
        [JsonProperty]
        public int Height { get; private set; }

        /// <summary>
        /// The size of the image in bytes.
        /// </summary>
        /// <remarks>Represented by the "<b>size</b>" JSON value</remarks>
        [JsonProperty("size")]
        public long FileSize { get; private set; }

        /// <summary>
        /// The number of views this image has received since being uploaded.
        /// </summary>
        /// <remarks>Represented by the "<b>views</b>" JSON value</remarks>
        [JsonProperty]
        public long Views { get; private set; }

        /// <summary>
        /// The amount of bandwidth which has been consumed by the viewing of this image.
        /// </summary>
        /// <remarks>Represented by the "<b>bandwidth</b>" JSON value</remarks>
        [JsonProperty("bandwidth")]
        public long Bandwidth { get; private set; }

        /// <summary>
        /// The deletehash key for this image.
        /// </summary>
        /// <remarks>Represented by the "<b>deletehash</b>" JSON value</remarks>
        [JsonProperty("deletehash")]
        public string DeleteHash { get; private set; }

        /// <summary>
        /// The section classification for this image. Section is assigned by Imgur to help categorize images automatically.
        /// </summary>
        /// <remarks>Represented by the "<b>section</b>" JSON value</remarks>
        [JsonProperty]
        public string Section { get; private set; }

        /// <summary>
        /// The URL link to the direct image on the Imgur site.
        /// </summary>
        /// <remarks>Represented by the "<b>link</b>" JSON value</remarks>
        [JsonProperty]
        public string Link { get; private set; }

        /// <summary>
        /// Flag denoting that this is a favorite of the current user. False if the current user is anonymous.
        /// </summary>
        /// <remarks>Represented by the "<b>favorite</b>" JSON value</remarks>
        [JsonProperty("favorite",NullValueHandling = NullValueHandling.Ignore)]
        public bool? IsFavorite { get; private set; }

        /// <summary>
        /// Flag denoting that this image is Not Safe For Work (nsfw).
        /// </summary>
        /// <remarks>Represented by the "<b>nsfw</b>" JSON value</remarks>
        [JsonProperty("nsfw", NullValueHandling = NullValueHandling.Ignore)]
        public bool? IsNSFW { get; private set; }

        /// <summary>
        /// The URL to the Imgur account that uploaded the image, if available.
        /// </summary>
        /// <remarks>Represented by the "<b>account_url</b>" JSON value</remarks>
        [JsonProperty("account_url")]
        public string AccountUrl { get; private set; }
    }
}
